import { _decorator, Component, EventTouch, instantiate, Node, Prefab, RigidBody, v3, Vec3 } from 'cc';
import { PrefsManager } from './PrefsManager';
import { LastLV, LV, WeaponData, WEAPONTYPE } from './GameConstant';
import { ResourceUtil } from '../AshFramework/Utils/ResourceUtil';
import { Pipe } from './Pipe';
import { Enemy } from './Enemy';
import { Weapon } from './Weapon';
import { NumberIncrementLabel } from './NumberIncrementLabel';
import { PoolManager } from '../AshFramework/Managers/PoolManager';
import { Bullet } from './Bullet';
import { ZTool } from '../AshFramework/Utils/ZTool';
import { BundleManager, Bundles } from '../AshFramework/Managers/BundleManager';
import { GameUtil } from './GameUtil';
import { AudioManager, Audios } from '../AshFramework/Managers/AudioManager';
import Banner from '../Banner';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    public static Instance: GameManager = null;

    @property(Node)
    WeaponParent: Node = null;

    @property(Node)
    CameraNode: Node = null;

    @property
    Speed: number = 1;

    @property(Node)
    GameTouch: Node = null;

    @property
    MinX: number = 0;

    @property
    MaxX: number = 0;

    @property(NumberIncrementLabel)
    Gold: NumberIncrementLabel = null;

    @property
    Force: number = 2000;

    @property(Node)
    Canvas: Node = null;

    @property
    DirZ: number = 0;

    @property
    BankNoteValue: number = 10;

    @property(Node)
    NewWeaponPanel: Node = null;

    @property(Node)
    SettlePanel: Node = null;

    @property(Node)
    LVParent: Node = null;

    @property(Node)
    LastParent: Node = null;

    @property(Prefab)
    LVs: Prefab[] = [];

    Pipes: Pipe[] = [];

    Weapon: Node = null;
    WeaponRigidBody: RigidBody = null;
    IsInit: boolean = false;

    offsetPos: Vec3 = Vec3.ZERO;
    dirX: number = 0;
    isMove: boolean = false;

    EnemyTs: Enemy = null;
    Muzzle: Node = null;
    IsFire: boolean = false;
    IsPause: boolean = false;

    Award: number = 0;

    private _dirZ: number = 0;

    protected onLoad(): void {
        GameManager.Instance = this;
        PoolManager.GenerateNodes("Prefabs/子弹", 30);
        AudioManager.StopAll();
        AudioManager.PlayMusic(Audios.BattleMusic);
    }

    protected start(): void {
        this.showMoney(100);
        this.initMap();
        this.initWeapon();
    }

    protected update(dt: number): void {
        // return;
        if (!this.IsInit) return;
        if (this.IsPause) {
            this.WeaponRigidBody.setLinearVelocity(v3(0, 0, 0));
            return;
        }
        this.WeaponRigidBody.setLinearVelocity(v3(this.dirX * dt, 0, dt * this._dirZ));
        if (this.Weapon.getPosition().x >= this.MaxX) {
            this.Weapon.setPosition(v3(this.MaxX, this.Weapon.position.y, this.Weapon.position.z));
            this.dirX = 0;
        } else if (this.Weapon.getPosition().x <= this.MinX) {
            this.Weapon.setPosition(v3(this.MinX, this.Weapon.position.y, this.Weapon.position.z));
            this.dirX = 0;
        }
        this.CameraNode.worldPosition = this.Weapon.getWorldPosition().add(this.offsetPos);
    }



    gameResume() {
        //继续游戏
        this._dirZ = this.DirZ;
        this.IsPause = false;
        this.anewFire();
    }

    gamePause() {
        //游戏暂停
        this._dirZ = 0;
        this.IsPause = true;
        this.unschedule(this.fire);
    }

    gameFail() {
        Banner.Instance.ShowBannerAd();
        Banner.Instance.ShowCustomAd();
        this.gamePause();
        this.showSettlePanel();
        const lastLv: LV = LastLV[ZTool.GetEnumKeyByValue(WEAPONTYPE, PrefsManager.Instance.userData.haveWeapon[PrefsManager.Instance.userData.haveWeapon.length - 1])];
        if (PrefsManager.Instance.userData.CurLV == lastLv) {
            PrefsManager.Instance.userData.CurLV = GameUtil.getAdjacentEnumCirculation(LV, PrefsManager.Instance.userData.CurLV, false);
        } else {
            PrefsManager.Instance.userData.CurLV = GameUtil.getAdjacentEnumCirculation(LV, PrefsManager.Instance.userData.CurLV, true);
        }
        PrefsManager.Instance.saveData();
    }

    //展示剩余的钱
    showMoney(number: number = 0) {
        PrefsManager.Instance.userData.Gold += number;
        PrefsManager.Instance.saveData();
        // this.MoneyLabel.string = String(PrefsManager.Instance.userData.Gold);
        this.Gold.playNumberIncrementTo(PrefsManager.Instance.userData.Gold);
    }

    //初始化场景
    initMap() {
        const path: string = ZTool.GetEnumKeyByValue(LV, PrefsManager.Instance.userData.CurLV);
        BundleManager.LoadPrefab(Bundles.Prefab_LV, path).then((prefab: Prefab) => {
            const lv: Node = instantiate(prefab);
            lv.parent = this.LVParent;
        })

        const lastPath: string = "Last_" + ZTool.GetEnumKeyByValue(WEAPONTYPE, PrefsManager.Instance.userData.haveWeapon[PrefsManager.Instance.userData.haveWeapon.length - 1]);
        BundleManager.LoadPrefab(Bundles.Prefabs, lastPath).then((prefab: Prefab) => {
            const last: Node = instantiate(prefab);
            last.parent = this.LastParent;
        })
    }

    //初始化武器
    initWeapon() {
        const path: string = "GameWeapon/" + ZTool.GetEnumKeyByValue(WEAPONTYPE, PrefsManager.Instance.userData.CurWeapon);
        // const path: string = "GameWeapon/UZI";
        BundleManager.LoadPrefab(Bundles.Prefabs, path).then((prefab: Prefab) => {
            this.Weapon = instantiate(prefab);
            this.Weapon.parent = this.WeaponParent;
            this.Muzzle = this.Weapon.getComponent(Weapon).Muzzle;
            this.WeaponRigidBody = this.Weapon.getComponent(RigidBody);
            this.offsetPos = this.CameraNode.getWorldPosition().subtract(this.Weapon.getWorldPosition());
            this.IsInit = true;
            this._dirZ = this.DirZ;
            this.scheduleOnce(() => {
                this.initData(this.Weapon.getComponent(Weapon).WeaponData);
                this.autoFire();
            })
        })
    }

    //被击退
    repulsed() {
        AudioManager.PlaySound(Audios.Forbid);
        this.WeaponRigidBody.applyForce(v3(0, 0, 1 * this.Force));
    }

    autoFire() {
        let time = this.Rate / 10 + this.AmpRate / 20 + 0.5;
        this.schedule(this.fire, 1 / time);
    }

    anewFire() {
        this.unschedule(this.fire)
        this.autoFire();
    }

    //发射子弹
    fire() {
        AudioManager.PlaySound(Audios.Fire, 0.3);
        PoolManager.GetNode("Prefabs/子弹", this.node.parent, this.Muzzle.getWorldPosition()).then((node: Node) => {
            const dis = 0.1 + 0.005 * this.Range + 0.0005 * this.AmpRange
            node.getComponent(Bullet).init(dis);
        })
    }

    pushTarget(target: Node) {
        this.Pipes[0].pushTarget(target);
    }

    removePipe() {
        this.Pipes.splice(0, 1);
    }

    onTouchStart(event: EventTouch) {
        this.isMove = true;
    }

    onTouchMove(event: EventTouch) {
        if (this.isMove) {
            this.dirX = event.getLocation().clone().x - event.getPreviousLocation().clone().x;
            // this._dirZ = event.getLocation().clone().y - event.getPreviousLocation().clone().y;
        }
    }

    onTouchEnd(event: EventTouch) {
        this.isMove = false;
        this.dirX = 0;
    }

    protected onEnable(): void {
        this.GameTouch.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.GameTouch.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.GameTouch.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.GameTouch.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    showNewWeaponPanel() {
        this.NewWeaponPanel.active = true;
    }

    showSettlePanel() {
        this.SettlePanel.active = true;
    }

    //#region 玩家数值方面
    Harm: number = 1;
    Rate: number = 1;
    Range: number = 1;

    AmpHarm: number = 0;
    AmpRate: number = 0;
    AmpRange: number = 0;

    initData(weaponData: WeaponData) {
        this.Harm = weaponData.power;
        this.Rate = weaponData.rate;
        this.Range = weaponData.range;
    }

    //增幅射速
    amplifiesRate(number: number) {
        AudioManager.PlaySound(Audios.Upgrade);
        this.AmpRate += number;
        this.anewFire();
    }
    //增幅范围
    amplifiesRange(number: number) {
        AudioManager.PlaySound(Audios.Upgrade);
        this.AmpRange += number;
        this.anewFire();
    }

    //全体增幅
    amplifies(number: number) {
        AudioManager.PlaySound(Audios.Upgrade);
        this.Harm += 1;
        this.Rate += number;
        this.Range += number;
        this.anewFire();
    }

}


